//
//  LIUFilterViewController.swift
//  functional
//
//  Created by liuyu on 2/10/19.
//  Copyright © 2019 LimitLiu. All rights reserved.
//

import UIKit

class LIUFilter: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        DispatchQueue.global().async {
            let url = URL(string: "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=935292084,2640874667&fm=27&gp=0.jpg")!
            let image = CIImage(contentsOf: url)!
            let blurRadius = 1.0
            let overlayColor = UIColor.green.withAlphaComponent(0.2)
            let filter = blur(radius: blurRadius) >>> colorOverlay(color: overlayColor)
            let result = filter(image)
            let img = UIImage(ciImage: result)
            DispatchQueue.main.async {
                let imgView = UIImageView(image: img)
                imgView.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
                self.view.addSubview(imgView)
            }
        }
    }
}

typealias Filter = (CIImage) -> CIImage

func blur(radius: Double) -> Filter {
    return { image in
        let parameters: [String: Any] = [
            kCIInputRadiusKey: radius,
            kCIInputImageKey: image
        ]
        guard let filter = CIFilter(name: "CIGaussianBlur",
                                    parameters: parameters) else { fatalError() }
        guard let outputImage = filter.outputImage else { fatalError() }
        return outputImage
    }
}

func colorGenerator(color: UIColor) -> Filter {
    return { _ in
        let c = CIColor(color: color)
        let parameters = [
            kCIInputColorKey: c
        ]
        guard let filter = CIFilter(name: "CIConstantColorGenerator",
                                    parameters: parameters) else { fatalError() }
        guard let outputImage = filter.outputImage else { fatalError() }
        return outputImage
    }
}

func compositeSourceOver(overlay: CIImage) -> Filter {
    return { image in
        let parameters = [
            kCIInputBackgroundImageKey: image,
            kCIInputImageKey: overlay,
        ]
        guard let filter = CIFilter(name: "CISourceOverCompositing",
                                    parameters: parameters) else {
            fatalError()
        }
        guard let outputImage = filter.outputImage else {
            fatalError()
        }
        return outputImage.cropped(to: image.extent)
    }
}

func colorOverlay(color: UIColor) -> Filter {
    return { image in
        let overlay = colorGenerator(color: color)(image)
        return compositeSourceOver(overlay: overlay)(image)
    }
}

infix operator >>>: FilterOperator
precedencegroup FilterOperator {
    associativity: left
}

func >>>(_ filter1: @escaping Filter, _ filter2: @escaping Filter) -> Filter {
    return { image in
        filter2(filter1(image))
    }
}

func add(x: Int) -> (Int) -> Int {
    return { y in x + y }
}
